
#ifndef _COMPOSITION_H_
#define _COMPOSITION_H_

#include <cstdio>
#include <cstdlib>
#include <string>

#include "common.h"

__BEGIN_NAMESPACE_DECL_

enum NoteInstruments
{
    NOTE_HIHAT = 0x01,
    NOTE_SNARE = 0x02,
    NOTE_KICK  = 0x04,
    NOTE_CRASH = 0x08,
    NOTE_TOM12 = 0x10,
    NOTE_TOM13 = 0x20,
    NOTE_TOM16 = 0x40,
    NOTE_RIDE  = 0x80
};

typedef struct Note_
{
    int      instruments;
    double   duration;
} Note;

class Composition
{
    public:
        Composition();
        ~Composition();

        bool loadFromFile (const char *filename);

        size_t getBPM();
        bool setBPM(size_t bpm);

        bool isLooped() const;
        void setLooped(bool looped);

        const char *getTitle() const;
        void setTitle (const char *title);

        bool getCurrentNote(Note &note);

        void reset();
        void next();
        bool isPlaying();

        void clear();

        // The following methods return the number of seconds
        // for the given note, based on the BPM (where BPM
        // specifies the number of quarter notes per minute)
        double getDurationSixteenth() const;
        double getDurationEighth() const;
        double getDurationQuarter() const;
        double getDurationHalf() const;
        double getDurationWhole() const;

    private:
        void addNote (double duration, const char *instr);
        void addNote (const Note& note);

    private:
        size_t bpm_;         // beats per minute
        size_t numNotes_;    // number of notes in composition
        size_t currentNote_; // current note, starting from zero (index into notes_ array)
        bool looped_;        // Whether or not the composition should loop after advancing
                             // past the last note
        size_t notesSize_;   // Size of the notes array (may be larger than actual number
                             // of notes in the array)
        Note *notes_;        // The array of notes in the composition
        std::string title_;  // title of composition
};

__END_NAMESPACE_DECL_

#endif
